remaining_candidates: RcVecIter<Rc<Summary>>,
parent: Rc<Summary>,
dep: Dependency,
+ features: Vec<String>,
}
/// Recursively activates the dependencies for `top`, in depth-first order,
}
None => continue,
};
- let (mut parent, (mut cur, (mut dep, candidates, features))) = frame;
+ let (mut parent, (mut cur, (mut dep, candidates, mut features))) = frame;
assert!(!remaining_deps.is_empty());
- let method = Method::Required {
- dev_deps: false,
- features: &features,
- uses_default_features: dep.uses_default_features(),
- };
-
let my_candidates = {
let prev_active = cx.prev_active(&dep);
trace!("{}[{}]>{} {} candidates", parent.name(), cur, dep.name(),
remaining_candidates: remaining_candidates,
parent: parent.clone(),
dep: dep.clone(),
+ features: features.clone(),
});
candidate
}
// their state at the found level of the `backtrack_stack`.
trace!("{}[{}]>{} -- no candidates", parent.name(), cur,
dep.name());
- match find_candidate(&mut backtrack_stack, &mut cx,
- &mut remaining_deps, &mut parent, &mut cur,
- &mut dep) {
+ match find_candidate(&mut backtrack_stack,
+ &mut cx,
+ &mut remaining_deps,
+ &mut parent,
+ &mut cur,
+ &mut dep,
+ &mut features) {
None => return Err(activation_error(&cx, registry, &parent,
&dep,
&cx.prev_active(&dep),
}
};
+ let method = Method::Required {
+ dev_deps: false,
+ features: &features,
+ uses_default_features: dep.uses_default_features(),
+ };
trace!("{}[{}]>{} trying {}", parent.name(), cur, dep.name(),
candidate.version());
cx.resolve.graph.link(parent.package_id().clone(),
remaining_deps: &mut BinaryHeap<DepsFrame>,
parent: &mut Rc<Summary>,
cur: &mut usize,
- dep: &mut Dependency) -> Option<Rc<Summary>> {
+ dep: &mut Dependency,
+ features: &mut Vec<String>) -> Option<Rc<Summary>> {
while let Some(mut frame) = backtrack_stack.pop() {
if let Some((_, candidate)) = frame.remaining_candidates.next() {
*cx = frame.context_backup.clone();
*parent = frame.parent.clone();
*cur = remaining_deps.peek().unwrap().remaining_siblings.cur_index();
*dep = frame.dep.clone();
+ *features = frame.features.clone();
backtrack_stack.push(frame);
return Some(candidate)
}
+use std::collections::HashMap;
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::{PathBuf, Path};
use flate2::write::GzEncoder;
use git2;
use rustc_serialize::hex::ToHex;
+use rustc_serialize::json::ToJson;
use tar::{Builder, Header};
use url::Url;
pub struct Package {
name: String,
vers: String,
- deps: Vec<(String, String, &'static str, String)>,
+ deps: Vec<Dependency>,
files: Vec<(String, String)>,
yanked: bool,
+ features: HashMap<String, Vec<String>>,
+}
+
+struct Dependency {
+ name: String,
+ vers: String,
+ kind: String,
+ target: Option<String>,
+ features: Vec<String>,
}
fn init() {
deps: Vec::new(),
files: Vec::new(),
yanked: false,
+ features: HashMap::new(),
}
}
}
pub fn dep(&mut self, name: &str, vers: &str) -> &mut Package {
- self.deps.push((name.to_string(), vers.to_string(), "normal",
- "null".to_string()));
- self
+ self.full_dep(name, vers, None, "normal", &[])
+ }
+
+ pub fn feature_dep(&mut self,
+ name: &str,
+ vers: &str,
+ features: &[&str]) -> &mut Package {
+ self.full_dep(name, vers, None, "normal", features)
}
pub fn target_dep(&mut self,
name: &str,
vers: &str,
target: &str) -> &mut Package {
- self.deps.push((name.to_string(), vers.to_string(), "normal",
- format!("\"{}\"", target)));
- self
+ self.full_dep(name, vers, Some(target), "normal", &[])
}
pub fn dev_dep(&mut self, name: &str, vers: &str) -> &mut Package {
- self.deps.push((name.to_string(), vers.to_string(), "dev",
- "null".to_string()));
+ self.full_dep(name, vers, None, "dev", &[])
+ }
+
+ fn full_dep(&mut self,
+ name: &str,
+ vers: &str,
+ target: Option<&str>,
+ kind: &str,
+ features: &[&str]) -> &mut Package {
+ self.deps.push(Dependency {
+ name: name.to_string(),
+ vers: vers.to_string(),
+ kind: kind.to_string(),
+ target: target.map(|s| s.to_string()),
+ features: features.iter().map(|s| s.to_string()).collect(),
+ });
self
}
self
}
- #[allow(deprecated)] // connect => join in 1.3
pub fn publish(&self) {
self.make_archive();
// Figure out what we're going to write into the index
- let deps = self.deps.iter().map(|&(ref name, ref req, ref kind, ref target)| {
- format!("{{\"name\":\"{}\",\
- \"req\":\"{}\",\
- \"features\":[],\
- \"default_features\":false,\
- \"target\":{},\
- \"optional\":false,\
- \"kind\":\"{}\"}}", name, req, target, kind)
- }).collect::<Vec<_>>().connect(",");
+ let deps = self.deps.iter().map(|dep| {
+ let mut map = HashMap::new();
+ map.insert("name".to_string(), dep.name.to_json());
+ map.insert("req".to_string(), dep.vers.to_json());
+ map.insert("features".to_string(), dep.features.to_json());
+ map.insert("default_features".to_string(), false.to_json());
+ map.insert("target".to_string(), dep.target.to_json());
+ map.insert("optional".to_string(), false.to_json());
+ map.insert("kind".to_string(), dep.kind.to_json());
+ map
+ }).collect::<Vec<_>>();
let cksum = {
let mut c = Vec::new();
File::open(&self.archive_dst()).unwrap()
.read_to_end(&mut c).unwrap();
cksum(&c)
};
- let line = format!("{{\"name\":\"{}\",\"vers\":\"{}\",\
- \"deps\":[{}],\"cksum\":\"{}\",\"features\":{{}},\
- \"yanked\":{}}}",
- self.name, self.vers, deps, cksum, self.yanked);
+ let mut dep = HashMap::new();
+ dep.insert("name".to_string(), self.name.to_json());
+ dep.insert("vers".to_string(), self.vers.to_json());
+ dep.insert("deps".to_string(), deps.to_json());
+ dep.insert("cksum".to_string(), cksum.to_json());
+ dep.insert("features".to_string(), self.features.to_json());
+ dep.insert("yanked".to_string(), self.yanked.to_json());
+ let line = dep.to_json().to_string();
+
let file = match self.name.len() {
1 => format!("1/{}", self.name),
2 => format!("2/{}", self.name),
version = "{}"
authors = []
"#, self.name, self.vers);
- for &(ref dep, ref req, kind, ref target) in self.deps.iter() {
- let target = match &target[..] {
- "null" => String::new(),
- t => format!("target.{}.", t),
+ for dep in self.deps.iter() {
+ let target = match dep.target {
+ None => String::new(),
+ Some(ref s) => format!("target.{}.", s),
};
- let kind = match kind {
+ let kind = match &dep.kind[..] {
"build" => "build-",
"dev" => "dev-",
_ => ""
manifest.push_str(&format!(r#"
[{}{}dependencies.{}]
version = "{}"
- "#, target, kind, dep, req));
+ "#, target, kind, dep.name, dep.vers));
}
let dst = self.archive_dst();